{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Deep Learning Models -- A collection of various deep learning architectures, models, and tips for TensorFlow and PyTorch in Jupyter Notebooks.\n",
    "- Author: Sebastian Raschka\n",
    "- GitHub Repository: https://github.com/rasbt/deeplearning-models"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Sebastian Raschka \n",
      "\n",
      "CPython 3.6.1\n",
      "IPython 6.0.0\n",
      "\n",
      "tensorflow 1.2.0\n"
     ]
    }
   ],
   "source": [
    "%load_ext watermark\n",
    "%watermark -a 'Sebastian Raschka' -v -p tensorflow"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Model Zoo -- Convolutional Autoencoder with Deconvolutions"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "A convolutional autoencoder using deconvolutional layers that compresses 768-pixel MNIST images down to a 7x7x4 (196 pixel) representation."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Extracting ./train-images-idx3-ubyte.gz\n",
      "Extracting ./train-labels-idx1-ubyte.gz\n",
      "Extracting ./t10k-images-idx3-ubyte.gz\n",
      "Extracting ./t10k-labels-idx1-ubyte.gz\n"
     ]
    }
   ],
   "source": [
    "import tensorflow as tf\n",
    "from tensorflow.examples.tutorials.mnist import input_data\n",
    "\n",
    "\n",
    "##########################\n",
    "### DATASET\n",
    "##########################\n",
    "\n",
    "mnist = input_data.read_data_sets(\"./\", validation_size=0)\n",
    "\n",
    "\n",
    "##########################\n",
    "### SETTINGS\n",
    "##########################\n",
    "\n",
    "# Hyperparameters\n",
    "learning_rate = 0.001\n",
    "training_epochs = 5\n",
    "batch_size = 128\n",
    "\n",
    "# Architecture\n",
    "hidden_size = 16\n",
    "input_size = 784\n",
    "image_width = 28\n",
    "\n",
    "# Other\n",
    "print_interval = 200\n",
    "random_seed = 123\n",
    "\n",
    "\n",
    "##########################\n",
    "### GRAPH DEFINITION\n",
    "##########################\n",
    "\n",
    "g = tf.Graph()\n",
    "with g.as_default():\n",
    "    \n",
    "    tf.set_random_seed(random_seed)\n",
    "\n",
    "    # Input data\n",
    "    tf_x = tf.placeholder(tf.float32, [None, input_size], name='inputs')\n",
    "    input_layer = tf.reshape(tf_x, shape=[-1, image_width, image_width, 1])\n",
    "\n",
    "    ###########\n",
    "    # Encoder\n",
    "    ###########\n",
    "    \n",
    "    # 28x28x1 => 28x28x8\n",
    "    conv1 = tf.layers.conv2d(input_layer, filters=8, kernel_size=(3, 3),\n",
    "                             strides=(1, 1), padding='same', \n",
    "                             activation=tf.nn.relu)\n",
    "    # 28x28x8 => 14x14x8\n",
    "    maxpool1 = tf.layers.max_pooling2d(conv1, pool_size=(2, 2), \n",
    "                                       strides=(2, 2), padding='same')\n",
    "    \n",
    "    # 14x14x8 => 14x14x4\n",
    "    conv2 = tf.layers.conv2d(maxpool1, filters=4, kernel_size=(3, 3), \n",
    "                             strides=(1, 1), padding='same', \n",
    "                             activation=tf.nn.relu)\n",
    "    \n",
    "    # 14x14x4 => 7x7x4\n",
    "    encode = tf.layers.max_pooling2d(conv2, pool_size=(2, 2), \n",
    "                                     strides=(2, 2), padding='same', \n",
    "                                     name='encoding')\n",
    "\n",
    "    ###########\n",
    "    # Decoder\n",
    "    ###########\n",
    "    \n",
    "    # 7x7x4 => 14x14x8\n",
    "    deconv1 = tf.layers.conv2d_transpose(encode, filters=8, \n",
    "                                         kernel_size=(3, 3), strides=(2, 2), \n",
    "                                         padding='same',\n",
    "                                         activation=tf.nn.relu)\n",
    "    \n",
    "    \n",
    "    # 14x14x8 => 28x28x8\n",
    "    deconv2 = tf.layers.conv2d_transpose(deconv1, filters=8, \n",
    "                                         kernel_size=(3, 3), strides=(2, 2), \n",
    "                                         padding='same',\n",
    "                                         activation=tf.nn.relu)\n",
    "    \n",
    "    # 28x28x8 => 28x28x1\n",
    "    logits = tf.layers.conv2d(deconv2, filters=1, kernel_size=(3,3), \n",
    "                              strides=(1, 1), padding='same', \n",
    "                              activation=None)\n",
    "    \n",
    "    decode = tf.nn.sigmoid(logits, name='decoding')\n",
    "\n",
    "    ##################\n",
    "    # Loss & Optimizer\n",
    "    ##################\n",
    "    \n",
    "    loss = tf.nn.sigmoid_cross_entropy_with_logits(labels=input_layer,\n",
    "                                                   logits=logits)\n",
    "    cost = tf.reduce_mean(loss, name='cost')\n",
    "    optimizer = tf.train.AdamOptimizer(learning_rate)\n",
    "    train = optimizer.minimize(cost, name='train')    \n",
    "\n",
    "    # Saver to save session for reuse\n",
    "    saver = tf.train.Saver()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Minibatch: 001 | Cost:    0.693\n",
      "Minibatch: 201 | Cost:    0.153\n",
      "Minibatch: 401 | Cost:    0.104\n",
      "Epoch:     001 | AvgCost: 0.232\n",
      "Minibatch: 001 | Cost:    0.098\n",
      "Minibatch: 201 | Cost:    0.096\n",
      "Minibatch: 401 | Cost:    0.093\n",
      "Epoch:     002 | AvgCost: 0.093\n",
      "Minibatch: 001 | Cost:    0.090\n",
      "Minibatch: 201 | Cost:    0.086\n",
      "Minibatch: 401 | Cost:    0.089\n",
      "Epoch:     003 | AvgCost: 0.088\n",
      "Minibatch: 001 | Cost:    0.086\n",
      "Minibatch: 201 | Cost:    0.089\n",
      "Minibatch: 401 | Cost:    0.085\n",
      "Epoch:     004 | AvgCost: 0.086\n",
      "Minibatch: 001 | Cost:    0.090\n",
      "Minibatch: 201 | Cost:    0.083\n",
      "Minibatch: 401 | Cost:    0.087\n",
      "Epoch:     005 | AvgCost: 0.084\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "\n",
    "##########################\n",
    "### TRAINING & EVALUATION\n",
    "##########################\n",
    "    \n",
    "with tf.Session(graph=g) as sess:\n",
    "    sess.run(tf.global_variables_initializer())\n",
    "\n",
    "    np.random.seed(random_seed) # random seed for mnist iterator\n",
    "    for epoch in range(training_epochs):\n",
    "        avg_cost = 0.\n",
    "        total_batch = mnist.train.num_examples // batch_size\n",
    "\n",
    "        for i in range(total_batch):\n",
    "            batch_x, batch_y = mnist.train.next_batch(batch_size)\n",
    "            _, c = sess.run(['train', 'cost:0'], feed_dict={'inputs:0': batch_x})\n",
    "\n",
    "            avg_cost += c\n",
    "\n",
    "            if not i % print_interval:\n",
    "                print(\"Minibatch: %03d | Cost:    %.3f\" % (i + 1, c))\n",
    "\n",
    "        print(\"Epoch:     %03d | AvgCost: %.3f\" % (epoch + 1, avg_cost / (i + 1)))\n",
    "    \n",
    "    saver.save(sess, save_path='./autoencoder.ckpt')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:Restoring parameters from ./autoencoder.ckpt\n"
     ]
    },
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAABIEAAACqCAYAAAA6El8nAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzsnXW4XNX5hd9TWigtpXiAQBIkSHAIgeDuJVhxl6BFCwR3\nh+IWrEiLF3eCBYIlQLHgIThBi/ZHac/vj2SdvWeunbl3fNb7PHnu5My5M3u+u/c+e85e3/qSNE0x\nxhhjjDHGGGOMMc3NL2rdAGOMMcYYY4wxxhhTeXwTyBhjjDHGGGOMMaYF8E0gY4wxxhhjjDHGmBbA\nN4GMMcYYY4wxxhhjWgDfBDLGGGOMMcYYY4xpAXwTyBhjjDHGGGOMMaYF8E0gY4wxxhhjjDHGmBag\nRzeBkiRZK0mS15MkeStJkmHlapQxxhhjjDHGGGOMKS9Jmqbd+8UkmQx4A1gd+AB4FtgiTdNXy9c8\nY4wxxhhjjDHGGFMOftmD3x0EvJWm6TsASZJcBwwBOrwJNMMMM6T9+vXrwVs2LmPGjPk8TdMZ857v\nWDlWeSg1VtC68XKsSsPjMD+OVX48DvPjWJWGx2F+HKv8eBzmx7HKj2NVGp6z8pM3Vj25CdQbeD/6\n/wfAUsUnJUkyFBgK0KdPH0aPHt2Dt2xckiQZn+McxwrHqhTyxGrSeS0fL8eqNDwO8+NY5cfjMD+O\nVWl4HObHscqPx2F+HKv8OFal4TkrP3n7VsWNodM0HZ6m6cA0TQfOOGNJNzxbDscqP45VaThe+XGs\n8uNY5cexKg3HKz+OVX4cq/w4VqXheOXHscqPY5Ufx6o0enIT6ENg9uj/s006ZowxxhhjjDHGGGPq\njJ7cBHoW6J8kyRxJkkwObA7cXp5mGWOMMcYYY4wxxphy0m1PoDRNf06SZC/gPmAy4PI0TV8pW8uM\nMcYYY4wxxhhjTNnoiTE0aZreDdxdprYYY4wxxhhjjDHGmArRo5tApjE5/fTTAfjxxx+zYy+++CIA\nN910U8G5u+++OwCDBw/Ojm2zzTaVbqIxxhhjjDFmEv/3f/8HwDLLLJMde/755wFYf/31Abj11lur\n3zBjTMNR8epgxhhjjDHGGGOMMab2WAnUQmy22WYA3HjjjR2ekyRJwf8vuugiAB588MHs2IorrghA\nnz59yt3EpuCNN97IHs8777wAnHPOOQD86U9/qkmbasX3338PwIEHHgiE/jRw4ECgsC/27du3yq0z\nxhhTDb766isA3nvvvXafj+f/M888E4AFF1wQgHnmmQeARRZZpJJNNDVm5MiR2WMpXV5//XUA7rzz\nTgDuuusuANZdd902vy/F+vLLL1/RdtYCKYD2228/AF544YXsOa3bl1hiieo3zBhTwNFHHw3AMccc\nA8BKK60EwMMPP1yjFnWMlUDGGGOMMcYYY4wxLYCVQC1AHgXQfPPNB8Baa60FwDvvvAPA7bffDsBb\nb72VnXvNNdcAcOihh5a/sU2A8rMBfvGLifdZe/fuXavm1JSPPvoIgEsuuQSAySabDIDRo0cDcMcd\nd2Tn7rXXXlVuXe147rnnANhoo42yY++++263X+/+++8HYP755wdg9tln737jmoS4b8kr4dxzzwWC\n15n6YzMwYcIEADbddFOg0DNi6NChAPTr16/H7/Ovf/0re/zYY48B4brxq1/9qsevbxofqTbiMfjI\nI48A8Oabb7b7O1LNQpgLpX4Q//vf/8rYSlNrvvnmGwC22morAEaMGJE9N+WUUwLwn//8B4Bvv/22\n4Hc198Tod377298CcOGFFwKwySablLPZNUFq8osvvhiAVVddNXvu2GOPBWDppZeufsNM0yL1pr7T\n3HvvvQCcdtppQGHmyB//+EcgKDoPOOAAAHr16lWdxtYRjz76aMH/de3TTwjqoFpjJZAxxhhjjDHG\nGGNMC2AlUJMipQXALbfcUvCc8uyl8gGYYYYZAJhqqqkA+OmnnwBYaqmlAPjnP/+ZnfvFF19UoMXN\nQ5yrrXjGio9m57PPPsseb7fddjVsSf1y3333AW13uruLxvLll18OwHXXXVeW121END9J7RMjT66d\ndtoJCDvHjYx26xZYYAEgKHXiHbhyKoAWX3zx7Njnn38OhOtN//79e/w+tUCKBIBhw4YB8MorrwDB\nD88qp7a8/fbbAJx//vkADB8+HAiVR9M0zf1a8n4xrcPBBx8MBOVYjPqQ1K0zzTQTAFNPPXWbc6UQ\nk1+QflfzvDylABZeeOGytL3afPzxxwX/X2211bLHVgCZniLF3RlnnJEdO++884C2fU8KoFgJVFxZ\nWmsDrUlbiVjx09FxK4GMMcYYY4wxxhhjTNWoeyWQ7i7KUwRg1llnBeDXv/41EPKJZ5555uycueee\nu1pNrEviO7fajZMCSCqEWWaZpcPfP/300wEYO3Zsm+fWW2+9srWzmXjppZeA4DsCsO2229aqOVVH\n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\nNgHgxBNPBJwOZkwtkNXKjz/+CMAvfznxVks9ft9pzW+kxhhjjDHGGGOMMS2GlUAtwOuvvw7A0KFD\nAXjttdcA+M9//pOdox2Df//730BQbuiO5rBhw7Jzl156aQAWWmihSja7YZkwYUL2WHHr3bs3AEce\neSQAv/rVr6rfsBrw008/AbDiiisC8MorE23DZGD4yCOPZOdOP/301W2caWpi43vNdVLiaWemmdCc\n/fPPPwOFBv6tMt+Y+kJ9MX6s3dHPP/8cgPfffx+AaaedNjtX4/X+++8HYNtttwUKC1SY5kFz1/ff\nf58de+655wD417/+BcDHH38MwPjx4wH4/e9/n527/PLLAzDjjDMCMNNMM7U5p9HRuDnssMMA+PDD\nUIz5d7/7HQBrrrkmAFNNNVWVW2daAY3T4rUGhDWV1h2TTTZZlVtXexSXPffcE4B//OMfQLi2jRkz\nJjv3t7/9bZVb1z5WAhljjDHGGGOMMca0AM23HWqAkCMMsMEGGwAwbtw4AGaYYQYAlltuuewc5Rm/\n++67QPCy0e6DfgLcd999gJVAxUh5MHz48OzYrbfeCgT1VKt5Aj388MNA2NWTMuitt94C4IQTTsjO\nPf3004HWiJHG59dff50dm3XWWYHuff5Y9QKFKpBW5fnnn88eX3XVVUCI8c477wzAdNNNV/2GlRmp\nJi677DIArrnmGqBQWaFj5dgZ//LLL7PHUnFIoRG/p2k9vvjiCwAeeOABAO66667sudGjRwNB0aFr\nQbFvXnxMP3VNfeONN7Jz5CtnGpdPP/0UgD322AOAkSNHZs998803QPuqAyjsL1Ky6zo49dRTA3D0\n0UcDsOuuu2bnNur6QtczqQniuVz+nmuvvTbg678pD/red+eddwJw5plnAvDDDz8AYYwCzDPPPADM\nPffcAOy3334AzDXXXNVpbB2gOeqWW24B4LPPPgPC92spgwC22WabKreufRpzNjTGGGOMMcYYY4wx\nJdEwSqB4p1u+NbrbLb+D+A5/q98Jj6t7ffTRR0CI0/bbbw/AVlttlZ0jldA777xT8FN3gBVzKLz7\nawLKXf/73/+eHdNO5mabbQa0Rp6s+hKEnbhipcr//d//AUG9ALD++usDsNJKK1W2gTVEn/u4444D\n4De/+U32nHbzSskV1i7pq6++CsDTTz8NwNZbb52d02oVQp555hkANt544+yYdmKkBNpuu+2q37Ay\nEu+Kn3XWWQAcddRRQOgTyyyzTHZOOTyQXn75ZQB22GGH7Jjief755wONpwTSvCSvMgi7dYsuuigA\nq622GgBTTjkl4LVFjPrhDTfcAMABBxwABLWY+mL8WD+L41h8jYCwptO8GSuBFl544Z5/gDojHteK\nR3Fl0UZVssRIvahrvXwqY6T0kuJF10WNQ1WyhbAmVT+R39RBBx0EFM5/u+yyS3k+RJVQP7j66quB\n8LkPOeSQ7BwpqVphfVkuihVm6pPxPKS1U7HfTTOiOJx00knZMfU5+XBJvdneXCSPKvl83nPPPQA8\n+uijAMw222yVanrdoPhIKaW+pL4VKx2tBDLGGGOMMcYYY4wxVaNulUDFO3RHHHFE9pxUKrrrph2h\n+E7jvPPOC4SqRMpX7Azd5W0Gf4240pJ2UJQnrR3imWeeOTtnjjnmAGCFFVYAQm6/PF3iSmKNtttb\nLZ566ikg+CpBqFKx7rrr1qJJVaF4rJ588snZc1JCaTdPHjjt7SSoEszgwYOB5lSwvPnmm0DYOZdX\nFMDkk09e8uspfqNGjQJCzvZ6662XndOrV6/uNbZBUT62doMh9FHNi41eiS5Wruhvrs8oBYviAD2r\nRKGd55122gkIfl4Ayy67LFB4LWkEFCsp5zbaaKPsOc1RmrtPPfVUIMzh9VLVo1ooVto5j69v119/\nPRD83KS46wzNc5rfNYfF89/ss88OhOuGqj/lWcc1AqqC9cQTTwBhDMdzlvqhvBcHDRoEwOqrrw7A\nIosskp3baNUOpVyVwkDEPjdbbrklEBSO8rIUsU+l/HIUx8cffxwIcdH/IVSaa5T1hcaU1uJS2cVK\ngkb7+1cbrUMhzPn6Tqnvk1LCqNIawHzzzQfAvvvuC4SMCFVfW3LJJbNzG7UCp+Z1+Saecsop2XNS\n1ik2+oxaP8XfjaXG07gs/g5ZL8qXaqA1gtZOurYtvvjiNWtTR1gJZIwxxhhjjDHGGNMC+CaQMcYY\nY4wxxhhjTAtQtxpCpR+pzJwkfPFzMkGTpFSGcRBkbJLtSSLfu3dvAN57773sXP2e5LV33313wbmx\n0a9er96ZccYZs8dKs1EqiiT8sSmtJNmSfr/00ksFvxMbzqkcsJmIYqZ+E7PqqqsCzZlCp88tU0cZ\nO8dlz9XHNGbVz3Q8Ng699tprgdD3DjvsMKAwZapR0eeXXF2yYhnrQvdMHfU3eOGFF4AQ+0ZMYe0p\nkiwrNSBO69Ucv+OOOwKNK5+XrP2KK67IjqlvycD4pptuAnqe7qD4Sc6tcvBxGorMzBstnipTLpPY\n9lIHZfQv83qtKWTyD91L4WwU1Ndef/11AF588UWg0MRX84zKAk+YMAEIsYvXZEqdUBqG1hGSzM8y\nyyzZuTIFLl6XNMK8prYqfooJhDXCiSeeCMB3330HhDEcp5RoPvvnP/8JhDSgu+66CyhMMd9tt90A\nmGaaacr5UcpKfK2/8sorgRArtfuYY47JztFn6miMxWtxpQtqbtL3BsVb5rQA55xzDhBMzOvRaDu+\ndsn4X8a75TLYLR5TjTTG8qIxdPbZZ2fH9PiTTz4BQv+SXYbSmCCMPfUnjVf9jtJhAQYMGFD+D1AF\nVERIRVziNEutSTU3K+1XY2/MmDHZuffeey8AY8eOBULsNQa32GKL7NxGWy/kRfHSGNJPHa/H7871\nN/sZY4wxxhhjjDHGmLLT5e24JEkuB9YDJqRpuuCkY9MB1wP9gHeBTdM07doRsAS0I3L88ccDcPnl\nl2fPyYBK5nraVY9387RrKXS3/7PPPgOC2gDCHXDtIGs3XTtgMvyFsNvaSCy44IJAuFPdngG27to+\n+OCDQDDPU4xjszQZE5qJKHbaMY/juskmmwDNWbpTu73qK1LkxZ+1uFRiZ6ivaXfh2GOPBYKyIVau\nNRoy6b3xxhuBsPOpHSbo3o6k1AkPPfQQEHaq4lLDrYL6mnbv2jOzV6GARkWqifvuuy87puufVC3l\nMjzVtVLGrIqv5jQoVG80AhoXe+65JxBMrtubn6Xk0LpA5cljE+yVV14ZaJ6dzXjeOOOMMwAYMWIE\nEFR02223XXaOlIwHH3wwEIp1KJ6xEqij+U0G3J3RCOoE7aBrR/yBBx4AgkoTYNy4cQXnyuh6rbXW\nAsL8DUFxpXlsuummA+CZZ54BgqIFgqpBJub1qFDTPAVBnS769+8PBPN56N5nkJpDc5RUCFJRQShd\nrWtvPSqBtBaCsGZQP5h//vmBwjmnFBWP5nWVAlfMpNTacMMNs3MXWGABIHwfa4RxCCEeUnEed9xx\n2XO6juk7jQqZSM2ocQuh3LnGrf4umt/iftVoqD/tuuuuQFCaxWt1KTIVI6lgdc5yyy2XnSvTY10L\n9H1A10+ZwUMo5tRsaM5SFpHGmsaWvjPVE3lmv78CaxUdGwaMSNO0PzBi0v+NMcYYY4wxxhhjTJ3S\n5fZVmqaPJUnSr+jwEGClSY+vBB4BDi5ju7I7zksttRRQWIpPdyF1B187dvHdc6l5tHui19NuhHIb\nIeRsq1ynckL1Pioh2OgU73jEd3x113bvvfcGQvy02xDfSY9VQSaoyrQbF+dsy4uqWYj7zDXXXAOE\nz6+73fE52kHSzonKvGrnLy4JK58OlSCWsuoPf/gDUOiDUo+5tcXE3kiHH3440NbrrLv5/YqxvBWU\n1635Lt6Bb3YUC+2Mq6RuPN/NMcccAPTr16+6jSsT+oxSamqugbD7VC5PAqkRdt55ZyCMS3l+7bDD\nDtm5jaZw1HVOO7y6vqnkLYS1gvqRlMdSGkv5CEElJf+SRkVrHs21EP7uf/zjHwHYaKONgM4VGto5\nbhU+/fTT7LHGhcqR63oY+zNKRbbCCisAod/onHitqZ356667DoDnnnsOCGM/VmVoXtD1pR6VQPEu\nuBQUaufaa68NhNLKPWWVVVYBgmpGagQIqg59b6hHFV+8dtA8JCW01KyxCkXXf63Npe6RUviOO+7I\nzpXXosZ8sY+J1hQQ+ulpp50GFKog6xmpp+RZF69JN9hgAwDOPfdcoK0ScbHFFssezzXXXEBYv2lM\n65x6LPmdlyeffBII62x9tthrS75ZW265JdD2eh97nWrMyavs/PPPB8J6XmoigL/97W9A4yjL8qLP\noxhKWau5RvcYADbffPOC36kV3dVB9krT9ONJjz8BenV0YpIkQ5MkGZ0kyWhJo0z7OFb5caxKw/HK\nj2OVH8cqP45VaThe+XGs8uNY5cexKg3HKz+OVX4cq/w4VqXR41vgaZqmSZJ0aPiRpulwYDjAwIED\nuzYG6YDO8nZ1Jz9WFcSPY3Q3Pa5CICXQ8OHDgVC5QefGd4YrSblilRftcALstddeQMhhVEy1M7jH\nHntk59b6ziVUP1btobu7yjuXEk25xRCUGbWmXPGKfVZUGUE+EO2hO+LafTnhhBOAsFOlGELwclH1\nBvkGKJdYvwthl6ESu3jlilU8x8h7RLtO8m/pLtrhU7Ux5bkrh79aVQzrYRzKX+Pmm28GQmzi3fBt\nttkGKKy+U216EivtZKpSZeyvob91PDaL0TjT3K3rqXb/4gpGUrqMHDkSCLvL22+/PVA9b65K9C3t\nSsqTSzuZQ4YMyc7RnK0d0rfffhsIHoFxrPT3kJdJrfpXd2Ola5Yqt8RKlHXWWQcIaqd6VJd0h3L0\nK40nxQZg1KhRQBiHGiexh5YUL7oOSAGk2M4777zZufp9rWXjqkXxcQjK2HJfD8s5BlVdDoK3mT73\nMsss05OXboN80dZYYw0grC0gXC90zSyXhxqUL16qsATheiaVlHzYYjWo5iZ9Tl0v5H+keQ/CtUPX\nAF0/dC2IvzjrmiovmPXWW6+7H6kNlZjf1XZ9n5GqVeMO4K9//SvQ8XUsPq7vSIqnlDDy0Wm0a2G8\n3pYyR/1LxGppxbGjeSX+LqhYyN9MPr4ab1IyQvi7VCKrpJZr0uIspY6qhNUT3VUCfZokySwAk35O\n6OJ8Y4wxxhhjjDHGGFNDunsT6HZAJSK2A24rT3OMMcYYY4wxxhhjTCXIUyL+WiaaQM+QJMkHwFHA\nycANSZLsBIwHNq1kI8uJZFqxBFSpKe+99x4QJFvLLrss0Hzl7CQJlJkgBBmpPrvMIC+88EKgtmkU\n9Ypk3yrPLTntxhtvnJ3TLBJ6EZsRqoStpI4aRzKRAzj66KOBfGWAZbK3/PLLA6EUrgwlZfYHwXB7\n9913L/1DVBjJzK+99trsmGSiSqnpabqW/g4yDxUq39xK41XmrLHkHQplzVtttRVQH6msPUHGxrGs\nWyaiGnftlYpX2WpJszXWNLYee+yx7FylX2o+kxnooEGDgMaLYWwKqs+vlF2lvi244ILZOTKA1tiS\nQbI+d/x6ipGuBY027pQuMmbMGKDwerX11lsD1Ut5aCSeffZZAG67Lex/at5XDGU2Puecc2bn6DmN\nWaXmKKU6vi7o+nffffcBoe+q/8Xje6GFFgLqs/+pvfocEAxTFaP55puvIu+ttZjSpqFtqkY9oVhp\nPEJop4o9yAQ6TtEp/l6jviKU/goh5VCprEoze+qpp4BghwHw8ssvA6HkdT0Sz8cq+KPrmj73sGGh\ngHVXRTPi9CilMGmcKg5xelkj8f7772ePlb4qFCtZLUBpdhbqg5qL9HpKqfvoo4+ycx999FGgvOmF\n9YDWZbJ/EPpeHae91sv8k6c62BYdPLVqmdtijDHGGGOMMcYYYypE/dVGrBLx3eOnn34aCEaYujN+\nwQUXAOU1jqsHVBrwT3/6U3ZMZpe9ek0s9KZS8R0ZbJtgdPjGG28AoZ+o9B/Uz93echHvJMjcTbuP\n6jOxIXIpn1/lhbVbqh1oqV7iHZq4NG+9oV2juL3atZMSqKdcddVVQNhB1pwlBV8rccYZZwCFRvcQ\nzG4hqNQaFe2yyRx9xx13zJ6TQajUnJrX42IK2qHSfC51ixQsMhaF0Kc0HlUeuFpm4+VGah0I85fm\naikU488mBZCUwZrfNa7jOU39qh7LTHeGYnL11VcX/F+mszH1XHa8VmhsxYqLYmN29Zd4bGlnXbHU\njrGURbHi4oEHHgDCDrrUM7reaq0GofBCZwVUaoX61gsvvJAd02eRyr5SShON67j0vNRHmt/qCX0v\nidc3anv894ZCZYU+p4zGNY779+8PhAIvALPNNhvQdm0mE+1Y+XfQQQcBMOuss3br81SDuDBJrGiF\noBhXwQwIMS7+/Doer3GlhJKSQwbZcWn0RiKOj8zZNWdovbTccstl55Syfte5Gl9zzDEHEK6nsUox\nVmk3E10ZQMfG//VC/V0xjDHGGGOMMcYYY0zZaaztqzIiFQOEcn/KIz3iiCOAcCezWZCiQnd85X0A\nYWdqtdVWA2CJJZaocusaB+0YXHLJJUC4o77yyisD7e+mNgvxrqbioJ2qnXfeGei++km/p50D7aRq\n1zDeuVtqqaW69R7VoFh1AWG3pSe7j+pnAOeddx4Q/gbyL9MuTCugnXeVsdWOs1Qe8sZpJlR+NfbX\n2H///YEwNqVOiH2D1BeXXHJJIOzAqyR47KekHbsVVlgBgNVXX728H6LKxPOR+ox8j6Qii693zz//\nfMFP+bdI7ROXtdX4U6n1RlHLqG9IAazPIYUYwEknnQSEMsHrrrsu0Hiqp0og34vYSypWukCY6xVj\nCGNU4+6RRx4BgvIjVp2rTxUrgPSesZJ7kUUW6cnHqShaV8dxUGykUKlUn9KOfKzS0uN6LNdc7DEG\nYe7WmJW/W6w0llJHaqE+ffoAQXmcx9dL86SuEQArrrhi7t+vFfHfUf1KP9tToc0+++xAWCtpzpbi\n87DDDsvO1XVR/jZSuzcqxXMUhL/tDjvsAPRcTah5St8HRo8eDRSqsUvxGmokin0D44wjqE9FupVA\nxhhjjDHGGGOMMS1Ay23p6G567J0hTwXdRdfd82bxc9HdyEMOOQQozCUWM8wwAwD77rsvUJ9VJuoF\nVQFRNQXt2my66cQiefW4w1QubrrppuyxPrfubvdUAaV+Ki8OKdWU8x1XuFCuez2iXajYZ0S7uqr4\nUkpOtFSLUv9AUPVpPltnnXWA+vSEqBRvv/02EJQaQj4veSrSNSpSIkChKgg6v25pjEktdMoppwCF\nO/HyTzjnnHOAxu9Tcfs1R2luGTduHBD8V6Dtbp7Gs3aQ55prruxcXQu0O69qRPWuCNJnk7pQao1Y\nbagdXK0JrrjiCqDQH6Rv375AUI3p/2+++SZQ6K8hz5FmGJeqMBRXrDz22GOB4DFZrEyEUJVPc1Zx\nP5HqB8IaTMozxfjkk08G2q86Vo9IsRJXFtV8U2mV4Q033ADAV199lR0rVgfV01pXc0/sY6a/rdbt\nWg/Ec7bWAeqX+kzdUfDEfycp1jTPxSrIeiGe3zW3SEUuD5y4Ym9xhofiqWti7C2ov4e8hRrVF09o\nXoZwDdBnKnfmiyr+teefJrV/PXtNdQeNw2IFkLIl9D27nmjs1Z0xxhhjjDHGGGOMyUXLKYFeeeUV\nIKg4IOz0nX766UCh4qAZ0M6UVBzaQYh3jLUjE+8wm/YZMWIEAB988AEQKjI0c+x0h1s+GRB2q+RT\n0tMdNe3K33HHHUBQz4h4XMbVPuoNxSHeAdbOr/xbtKunHSYIO1LaRVC1p4ceeggIlSog7Kpo7pp5\n5pnL/Cnqk9jn5uCDDwaCUkzz2jLLLAM0j5KzK0pR6igmiuPjjz8OFFY7UeWxZqzgMWTIECCoWjSX\nxxVmNP60M3r44YcDYcdUPi4ADz/8MABHH300ENTEq6yySiWaXzY0VlQJRn4YMZp/NdfoeherC9SP\nNOdJtSC/jXhX/aijjgKC94Q8Ixp57orVr6omK98fzfGxSkdrBSlTHnzwQSAoOOL5bZ555gHg4osv\nBoLvTz2rftpD6oNYjaO4VaoqmNRH5557LlAYV/W3evS2khJM2QkQfLqkbtHaJ1ZDSwmsuA4aNAjo\nuBJWe2isSvkHQSGo/lmPxNc/ebyNHTsWCNX34r//+PHjgaBq+uyzzwpeR6onCH5MmicbVeWvz694\nQFula7k/m5R2Gouxuk3fSWP/qWZA47e4Uq0+e6xarxd/ICuBjDHGGGOMMcYYY1oA3wQyxhhjjDHG\nGGOMaQHqTw9ZISSH22OPPYAgrQRYeumlgVAevdGNMKHQYPDEE08Egumj5H/zzjtvds6f//xnoL5M\n8uqJWE7617/+FQh9SEaqc889d9XbVS0kHY3TJiSnVpnX7hDLJmXWHsvG4/fZfffds2NKu6hHlAam\ndAcIpqGSyJ599tltfk9jVuUz9TqSK3/xxRdtfkdjWSZ8zU4cgyeffBJoa3B4wAEHAPUp968XZPqr\n9E7J3gHWXnttoDnjp1QapZw+8cQTAFx33XXZOQMGDABgiy22AEIaqq4BsTnoiy++CASZ/bXXXgvA\nSoSb53EAABNRSURBVCutBNTvWkLtkvm3Uo3UfghpE5KwS9YfpyMpVUzPxesqaCuLBzj//POBYA6q\n/9drrPKilBvNxUrnitdiiqVSfBQDXVfjlIklllgCCGnmjZYGpnlZnzFGY6pSc8yoUaOAYAAfp5Jv\nsMEGQH2vdeM+o7Gl/jVw4EAADjrooOwclYRXSo/WBXqdzj6r0p9OO+00oDDtfKeddgLq0xC6PWab\nbTYAnnvuOSCksKogB4RUMa0fFFfFTGXhIfQbpYM16hylz9heWqBS/co9vzz77LNAmAfiNOIFF1yw\nrO9VLyiGSvXSfK/5PV6/aszWmsbs0cYYY4wxxhhjjDGmJJpvq68I3YW89NJLgWAMHSsJDjvsMKBw\nN7SZkJJAuwRSGMQlAYtL2pUb7XBpZyK+I90Id9fjnRmZaGp3RQqyejbP6ynqH/GOmu5ya0dFCoL4\nb6vfU/y0M6ed80MPPTQ7V0bIQq+z2GKLAbDNNttkz9Vzn1G7hw4dmh2TcaMMH1V6VbtSEBRAUiZq\nnGpXa9iwYdm5ir3eq1IGm/WGdtAhqBA0DqXIU38xbZGaZa+99gLCLrB2OqHQJLpZ0bVw+eWXB2Dw\n4MHZcxpTxSoF/U68i6lx99JLLwFw8803A2G8S3UQv249oZ1LqSy32mqr7DkpgbR7qf/L1BNCgQ2V\nlZ4wYQIQDGWlfIzRNUCvo2tDoyldukLXqFiFobiotLxUrzonLpmsv4kUCo2Grv2KQzye9JzWheUy\npdV8JsW/+pRUVRAUx/U4HtuLleZsGUJr3R6Xm9ZnUXGJMWPGAGGdFSuF1Z9k2C1z8ldffRUI6w+A\nXXbZpeD1GwXFT8UNYgP3ueaaCwgxkSpWRRKkHoJgIh5nTTQi6ldxIRL1Da0l9T2xp0VXdC24/vrr\ngTAGZ5999uycZlUCaR7TGkrXTCmBHnjggezcelmn1u83KWOMMcYYY4wxxhhTNrpUAiVJMjtwFdAL\nSIHhaZqenSTJdMD1QD/gXWDTNE2/6uh1aoVUCirzqt3j+C6cdgEb7W53Xorz9PV/5RpD2InqaGcm\nPlfP6WdxWbzHHnssO1cqhttuuw0IOxXx6yvvePPNNy/xk1UP7V4CfPrpp0D4DNoNLqUcZ6OhnYT4\nbr5UGVdffTUQdqZmmmmm7Jx77rkHgBdeeAEIsdNuVOwZUdzn9HrnnXceUKhCagTiz9O3b9+Cn0st\ntVSXv6/+JIVivBuleOqcSiv56oWHHnooe6w5SXFedtllgfpWidUazWPjxo0DgtpszTXXzM5p1DK4\n3UFzdSn+ICrzDcE/6O677waC8uWaa64BYN11183ObQSlS1y2Vl40Qtf5eO20wgorAGGe10/5D6p/\nxUjZIE+EZvSeionVUPKGkyJd87ZUxAceeGB2brxr34gUrxmmn3767Dld29WnejrnSFEl5Z1UDnrP\neG2pa3A9E1/PixVlUlpIuQNBsXLXXXcBQXEg5XG8Jv3++++BoJqSV4sUMvIQhfopY91T4rl34YUX\nBqB///5AmMO1toj9P5dZZhmgcTyRukKfHeDWW28Fwhr8sssuA+CII47IzinlmqWxLJ889U/Nf1qf\nQfOqjTW2OkLff6F+vi/mWS3/DByQpukAYGlgzyRJBgDDgBFpmvYHRkz6vzHGGGOMMcYYY4ypQ7rc\ngknT9GPg40mPv02SZCzQGxgCrDTptCuBR4CDK9LKbqDca/ly6A6ddvFOP/307Ny42kezEHvYKBa6\nw638xNgxX2oceRlIzSGfljiXUXcziz2U9PpxNQgdk8JIdz3jvNNbbrkFKMxFrjfk9QAhh1a7nPHd\n3WZFf7d4R0SqOo0t7WLG3kjqa+oH+qnYxTte+j3tSJ111llAyOev9R3zaqPPq7EY78op9tpl0W5O\n7BPQTKifxONQn127VfJ3sRKoY6TUEIpV7MclXxftLjuehcTzm66bqoSia+rIkSMBuPfee7Nz11tv\nPaBx4ynFTqz0VBUmVdSRAqj4dyDMZ1pv7bjjjkDjxqMrNGdJBQ1tFWOKpapFbrrpptm5zRIXXbdi\nhYV8WPbZZx8AjjrqKKDQq7P48yueUhMfc8wx2XO6LkgRJGWRqt5uueWWHb5uPVGsaoWg+pXy9dFH\nHwXg7bffzs7RGkxrU/l4aa5qz5tLf5fVV18dCNXB4vHdLMRrRymqdExeOIpnXLVJ/adZ1LHbb799\n9liePfrcN910E1BY7VeV6DoaM/H6XdeAk08+GQjfi1Sx7cgjj8zObZZ4QuF37b333huA1157reAc\nXQfjNXwjKYEykiTpBywGPA30mnSDCOATJqaLtfc7Q5MkGZ0kyWgNNtM+jlV+HKvScLzy41jlx7HK\nj2NVGo5Xfhyr/DhW+XGsSsPxyo9jlR/HKj+OVWnkTsZOkmQq4GZg3zRNvymqAJQmSdKuKUWapsOB\n4QADBw6sqHFFfFdSFb+UG6w7cMqDXHzxxSvZlG5RqVhpR1e7JFIR6P8QdvC066C7m/FdTqG7wvr9\nYl+FWFmlnGwdk0v/Iosskp0jT524WllXVKtfScF0//33Z8cUE6mZllxySaD2d3Q7o6fx0t98/fXX\nz46NGDECCLtQiov6V3ys2LNGcY13GNQPlJOs3bBq7xpUc87Kgz5/XLWiOH49rejQXaoVK/Uf7XDG\nSN254oorVurty0It+5XiJ9WlkCIv7ltSC8lHo9n7Vk/QLqd2UXfeeWcAbr/9diDsJENYc+h3ykk1\nYxUrOl5++WUgVDmUWkE7n/E1Uf1Ifmgrr7xyJZvZIdWK1euvvw4UVomUUkOeeFtvvTUQKlbVm0ql\nHLGSskLeMwAfffQREHxIrr32WgBWXXXV7Bx5AOqn1huqzhr7VAqpQrUjf8ABBwDVW5uVa50VV0KV\nokLfXaSEUv+C8PmKFT9ak8fVsVSBTpW/pPyotjdXred3XRPPPPNMIKip4zWuvjvVmnLFKlbanXvu\nuQAcdNBBQFBESYEPwUt37rnnBtp6BMVZEMcffzwQqqwpvieddBIQqt9Wmmr3K1XZgzBGi314Na7j\na169zPW5WpEkya+YeAPob2ma/mPS4U+TJJll0vOzABMq00RjjDHGGGOMMcYY01O6vAmUTLzFfBkw\nNk3Tv0RP3Q5sN+nxdsBtxb9rjDHGGGOMMcYYY+qDPPq/ZYFtgJeSJHlh0rFDgZOBG5Ik2QkYD2za\nwe9Xjeeffz57/Pe//73gORke12MaWCWQ3BiCad5TTz0FBGO5Bx98MDtHMkGVjZTJV3EZSQjGvUqx\nUxrG2muvDRSWshZKaZFEMJaeKrWlPfO6WqO2tWf+LJnyfPPNV9U21ZItttgie6y/1yWXXAIEWWT8\nd5TksTh9Sf1NxnMAO+ywAxAk4c1kHtcTOitjrXHerCU3heaN+HMqHvPPPz9Qu7SlRkDjT2m/6lMy\nblcpYQhpFvU4H9crGoennnoqAE888QRQeN0455xzADjllFOA+k4f7ow4pUBztVJ19HmVZqhUTYA5\n55wTgN133x1onrLLxagQx2qrrVbwfwh/c6VIKRWjma91Wifq7w7BJFap40rFiU20i9MllFqulJR4\nvldBBKXyKAWlGcaYUko32GADIJTg1piDkGqjuVvzkdJ4VllllexcjUOtweslLaXaPPfccwDcd999\nQBiDw4aFQteN2n86Iv48gwYNAmCPPfYAQmqmihwA7L///gAMGTKk4KfmNJlAQ0g1V7qwvnNvtNFG\nZf4U9UWcHi00ttSn1lprLQAWWGCB6jUsJ3mqgz0OdDQSVu3guDHGGGOMMcYYY4ypI6rrBFYhtMu5\n3377Zcd0p1K7BgMGDKh+w+oEmcJtuOGGBT8VN2h7x1s777rLGe9UdXR3vLt3zfXa9XjXXTGSmR4E\nBZB2m2R+3QrExnAq8as7/SqPPHz48OycL7/8EghmqNqpW2yxxYDCuGr3qpl3RbuD1Bqxkbt2/rTb\n3Owx03wU71pqvpASrx7nj3pBsdFP7cDLwDBWrGhXXWoOkx8ZicpUO96tV7n4PffcE4C+fftWuXXl\nIVbxaj5fZpllgHANmDBhokXkggsumJ3br18/oHoGobVCRrMffzyxeG5cFEFjSrvvzViOuyPU7yHM\nMVdccQUAY8aMAdo3e5biU/1unnnmAWDppZfOzpGKWOv8ZroeqqjKoosuWvAzNo8WxQU4iud9E2J0\n9tlnA0Hxqj4ppVSzo7X8mmuuCcC4ceOAYG4MoWDEMcccAwQFn9YL8XjV+l2qlyuvvBKovuF4tZGq\nE0JmgxSwUj8OHjwYqM9YtKYO0BhjjDHGGGOMMabFqL/bUt1Au09PPvlkdixWuUD9lPqrJzrLBdbO\nQTXzhesxN1l3y2OPqfbUUa2I/l7a2dUOgH5C2HXxTlT30U7gDTfckB2TH0L//v2B5u+L2kG55ppr\nsmMqK6xddfexjtFYPeGEE4CQ669d9X322Sc7d+GFFwaav09VAsX5qKOOAgq99HQNueOOOwDYa6+9\nqty68qM+Ig8TlZtuRaQouP7664G2a1CAJZdcEgjluVtpzoo97bbeemsAttxySyDETr4/AN9//z0A\nU045JRBUVMVlqluV9vpOK/Wn7qK+Jm8lzdlSArVaDPW55YWk9RSE79YXX3wxAOPHjweCV2z8vfry\nyy8HgpKqVeIozzOA+++/H2isz15/37qNMcYYY4wxxhhjTNlpaCWQVAY33ngj0H41E+XrrbHGGkBj\n3aEz9Yl3yPPj8dZztFMVV1JrVeQrAnDIIYfUriENinw0Ro0aVeOWNDfyR9h7772zY1I2yNPDNBdS\nCH/++ecFx2PliirwxAqxVkbXNql8Yh8yV3s0lUDrd1UnlNJskUUWAVpPaVZcfTb2OFXFZ6n79R1b\n53p9X0gjxsNKIGOMMcYYY4wxxpgWwDeBjDHGGGOMMcYYY1qAhk4HEyuvvDIAV111VXZMZlcXXXQR\n0FqlOI0xxhhTW2LTyAMPPBBwmkuzohSJLbbYAggG4FtttVV2ztxzz139hhljMpSCeNJJJwHhe6PS\nyxsxpafSKCatlirXClgJZIwxxhhjjDHGGNMCNLQSSHcnV1llFQBeeeWV7Lkff/wRgFlnnbXgXGOM\nMcaYShOvO6aaairAu6nNiv7Wxx57LBAUQLGhv1QIxpjaMnjwYADmmmsuAHr37l3L5hhTE3xFMsYY\nY4wxxhhjjGkBEpVZr8qbJclnwHhgBuDzLk6vJ8rR3r5pms6Y92THyrHKSUmxgixe35fhvauJY1Ua\nHof5cazy43GYH8eqNDwO8+NY5cfjMD+OVX5qGSuPwxw4Vl3Hqqo3gbI3TZLRaZoO7PrM+qCW7XWs\nGuO9u4NjlR/HqjQcr/w4VvlxrPLjWJWG45Ufxyo/jlV+HKv81Lq9tX7/UnHfyk812+t0MGOMMcYY\nY4wxxpgWwDeBjDHGGGOMMcYYY1qAWt0EGl6j9+0utWyvY9UY790dHKv8OFal4Xjlx7HKj2OVH8eq\nNByv/DhW+XGs8uNY5afW7a31+5eK+1Z+qtbemngCGWOMMcYYY4wxxpjq4nQwY4wxxhhjjDHGmBbA\nN4GMMcYYY4wxxhhjWoCq3gRKkmStJEleT5LkrSRJhlXzvfOQJMnsSZI8nCTJq0mSvJIkyT6Tjk+X\nJMkDSZK8OenntFVoi2OVvy2OVWntcbzyt8Wxyt8Wxyp/Wxyr0trjeOVvi2OVvy2OVf62OFaltcfx\nyt8Wxyp/Wxyr/G1xrLoiTdOq/AMmA94G5gQmB/4JDKjW++ds4yzA4pMe/w54AxgAnAoMm3R8GHCK\nY+VYNVqsHC/HyrFyrBopVo6XY+VYOVaNFCvHy7FyrByrRolVNZVAg4C30jR9J03Tn4DrgCFVfP8u\nSdP04zRNn5v0+FtgLNCbie28ctJpVwIbVLgpjlV+HKvScLzy41jlx7HKj2NVGo5Xfhyr/DhW+XGs\nSsPxyo9jlR/HKj+OVQ6qeROoN/B+9P8PJh2rS5Ik6QcsBjwN9ErT9ONJT30C9Krw2ztW+XGsSsPx\nyo9jlR/HKj+OVWk4XvlxrPLjWOXHsSoNxys/jlV+HKv8OFY5sDF0OyRJMhVwM7BvmqbfxM+lE/VZ\naU0aVoc4VvlxrErD8cqPY5Ufxyo/jlVpOF75cazy41jlx7EqDccrP45Vfhyr/NQyVtW8CfQhMHv0\n/9kmHasrkiT5FRP/GH9L0/Qfkw5/miTJLJOenwWYUOFmOFb5caxKw/HKj2OVH8cqP45VaThe+XGs\n8uNY5cexKg3HKz+OVX4cq/w4Vjmo5k2gZ4H+SZLMkSTJ5MDmwO1VfP8uSZIkAS4DxqZp+pfoqduB\n7SY93g64rcJNcazy41iVhuOVH8cqP45Vfhyr0nC88uNY5cexyo9jVRqOV34cq/w4VvlxrPKQVtcJ\nex0mul+/DRxWzffO2b7lmCi7ehF4YdK/dYDpgRHAm8CDwHSOlWPViLFyvBwrx8qxaqRYOV6OlWPl\nWDVSrBwvx8qxcqwaIVbJpIYYY4wxxhhjjDHGmCbGxtDGGGOMMcYYY4wxLYBvAhljjDHGGGOMMca0\nAL4JZMz/t2MHAgAAAACC/K0HuTACAACAAQkEAAAAMCCBAAAAAAYkEAAAAMCABAIAAAAYCOIXq8ii\nrkNiAAAAAElFTkSuQmCC\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x1264fbef0>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "%matplotlib inline\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "##########################\n",
    "### VISUALIZATION\n",
    "##########################\n",
    "\n",
    "n_images = 15\n",
    "\n",
    "fig, axes = plt.subplots(nrows=2, ncols=n_images, sharex=True, \n",
    "                         sharey=True, figsize=(20, 2.5))\n",
    "test_images = mnist.test.images[:n_images]\n",
    "\n",
    "with tf.Session(graph=g) as sess:\n",
    "    saver.restore(sess, save_path='./autoencoder.ckpt')\n",
    "    decoded = sess.run('decoding:0', feed_dict={'inputs:0': test_images})\n",
    "\n",
    "for i in range(n_images):\n",
    "    for ax, img in zip(axes, [test_images, decoded]):\n",
    "        ax[i].imshow(img[i].reshape((image_width, image_width)), cmap='binary')"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
